package service

import (
	"engine/PbMsgHelper"
	"time"

	"engine"
	"engine/log"
	"gitee.com/ameise84/e3dds"
	"google.golang.org/protobuf/proto"
	"servers/models/define"
	"servers/models/error_code"
	"servers/models/protos/google/pb/common_protos"
)

var service e3dds.NetService

func init() {
	var err error
	builder := &ActorBuilder{}
	service, err = engine.RegisterNetService(define.ServiceGWGame, builder)
	engine.SetNetMsgTransformHandler(builder)
	if err != nil {
		log.GetLogger().Fatal("RegisterNetService").Err(err).Println()
	}
}

type ActorBuilder struct {
}

func (a ActorBuilder) OnBroadcast(request e3dds.Request) {
	//TODO implement me
	panic("implement me")
}

func (a ActorBuilder) NetMsgToRpcMsg(actor engine.NetActor, bytes []byte) (string, []byte, error) {
	panic("implement me")
}

func (a ActorBuilder) RpcMsgToNetMsg(actor engine.NetActor, s string, bytes []byte) []byte {
	panic("implement me")
}

func (a ActorBuilder) ResponseError(err error) proto.Message {
	//TODO implement me
	panic("implement me")
}

func (a ActorBuilder) TakeActor() e3dds.Actor {
	return &Actor{}
}

func (a ActorBuilder) FreeActor(actor e3dds.Actor) {
	//TODO implement me
	panic("implement me")
}

type accountInfo struct {
	BusinessID string
	UserID     string
	GameKindID string
}

type Actor struct {
	e3dds.Behavior
	IsAuth  bool
	Account accountInfo
}

func (a *Actor) Load(s string, behavior e3dds.Behavior) error {
	a.Behavior = behavior
	a.IsAuth = false
	return nil
}

func (a *Actor) Unload(bool) {
	//if a.IsAuth {
	//	msg := &rpc_protos.DisconnectStandUpCast{}
	//	a.Behavior.Cast(a.Account.GameKindID, a.Account.UserID, msg)
	//	rdsCli := db.GetRedis()
	//	ctx := context.Background()
	//	pipe := rdsCli.Pipeline()
	//
	//	key := redis_help.KeyOnlineUserTime()
	//	f1 := redis_help.Join(0, a.Account.BusinessID)
	//	f2 := redis_help.Join(a.Account.GameKindID, a.Account.BusinessID)
	//	r1 := pipe.HIncrBy(ctx, key, f1, -1)
	//	r2 := pipe.HIncrBy(ctx, key, f2, -1)
	//	key2 := redis_help.KeyLoginGateway(redis_help.Join(a.Account.BusinessID, a.Account.UserID))
	//	pipe.Del(ctx, key2)
	//	_, err := pipe.Exec(ctx)
	//	if err != nil {
	//		log.GetLogger().Warn("actor on stop update user count failed").Println()
	//	}
	//	exp := time.Now().Add(30 * time.Minute)
	//	if r1.Val() == 0 {
	//		pipe.HExpireAt(ctx, key, exp, f1)
	//	}
	//	if r2.Val() == 0 {
	//		pipe.HExpireAt(ctx, key, exp, f2)
	//	}
	//}
}

func (a *Actor) OnTimer(behavior e3dds.Behavior, kind uint16, id uint32, now time.Time, ctx e3dds.TimerContext) bool {
	return false
}

func (a *Actor) OnRecvMsg(behavior e3dds.Behavior, req e3dds.Request) bool {
	if !a.IsAuth {
		req.ResponseMsg(PbMsgHelper.ToRpcMsg(&common_protos.GlobalResponseError{Code: error_code.ErrorCodeConnIsNotAuth}))
		return false
	}

	log.GetLogger().DebugPrintf("gateway[%v] OnRecvMsg[%v]", a.Account, req.ToJson())
	rsp := e3dds.TakeResponse()
	defer e3dds.FreeResponse(rsp)
	err := a.ForwardCall(a.Account.GameKindID, a.Account.UserID, req, rsp)
	if err != nil {
		req.ResponseMsg(PbMsgHelper.ToRpcMsg(&common_protos.GlobalResponseError{Code: error_code.ErrorCodeServiceBusy}))
		return true
	}
	log.GetLogger().DebugPrintf("req[%v] response:%v", a.Account, rsp.ToJson())
	req.ResponseForward(rsp)
	return true
}
